package com.plugin.mybatis.generator.tk;

import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Element;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.config.JavaModelGeneratorConfiguration;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;

/**
 * @author xiangshiming
 */
public class SimpleGeneratorPluginTk extends PluginAdapter {

    private static final String EXAMPLE_ROOT_CLASS = "exampleRootClass";
    private static final String EXAMPLEFLAG = "exampleFlag";
    private static final String APIMODELPROPERTYFLAG = "apiModelPropertyFlag";
    private static final String DTOFLAG = "dtoFlag";
    private static final String CLIENT_ROOT_INTERFACE = "clientRootInterface";
    private static final String CLIENT_ROOT_INTERFACE2 = "clientRootInterface2";
    private static final String CLIENT_ROOT_INTERFACE3 = "clientRootInterface3";
    private static final String CLIENT_ROOT_INTERFACE4 = "clientRootInterface4";
    private static final String CLIENT_ROOT_INTERFACE5 = "clientRootInterface5";
    private static final String CLIENT_ROOT_INTERFACE6 = "clientRootInterface6";
    private static final String CLIENT_ROOT_INTERFACE7 = "clientRootInterface7";
    private static final String CLIENT_ROOT_INTERFACE8 = "clientRootInterface8";
    private static final String CLIENT_ROOT_INTERFACE9 = "clientRootInterface9";
    private static final String CLIENT_ROOT_INTERFACE10 = "clientRootInterface10";
    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    @Override
    public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        String rootInterface = context.getJavaClientGeneratorConfiguration().getProperty(CLIENT_ROOT_INTERFACE);
        String rootInterface2 = context.getJavaClientGeneratorConfiguration().getProperty(CLIENT_ROOT_INTERFACE2);
        String rootInterface3 = context.getJavaClientGeneratorConfiguration().getProperty(CLIENT_ROOT_INTERFACE3);
        String rootInterface4 = context.getJavaClientGeneratorConfiguration().getProperty(CLIENT_ROOT_INTERFACE4);
        String rootInterface5 = context.getJavaClientGeneratorConfiguration().getProperty(CLIENT_ROOT_INTERFACE5);
        String rootInterface6 = context.getJavaClientGeneratorConfiguration().getProperty(CLIENT_ROOT_INTERFACE6);
        String rootInterface7 = context.getJavaClientGeneratorConfiguration().getProperty(CLIENT_ROOT_INTERFACE7);
        String rootInterface8 = context.getJavaClientGeneratorConfiguration().getProperty(CLIENT_ROOT_INTERFACE8);
        String rootInterface9 = context.getJavaClientGeneratorConfiguration().getProperty(CLIENT_ROOT_INTERFACE9);
        String rootInterface10 = context.getJavaClientGeneratorConfiguration().getProperty(CLIENT_ROOT_INTERFACE10);

        JavaModelGeneratorConfiguration configuration = context.getJavaModelGeneratorConfiguration();

        if (stringHasValue(rootInterface)) {
            interfaze.addImportedType(new FullyQualifiedJavaType(rootInterface));
            rootInterface += "<"+ introspectedTable.getFullyQualifiedTable().getDomainObjectName()+ ">";
            FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(rootInterface);
            interfaze.addSuperInterface(superInterface);
            interfaze.addImportedType( new FullyQualifiedJavaType(configuration.getTargetPackage() + "."+introspectedTable.getFullyQualifiedTable().getDomainObjectName()));
            interfaze.addImportedType(superInterface);
        }

        if (stringHasValue(rootInterface2)) {
            interfaze.addImportedType(new FullyQualifiedJavaType(rootInterface2));
            rootInterface2 += "<"+ introspectedTable.getFullyQualifiedTable().getDomainObjectName()+ ">";
            FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(rootInterface2);
            interfaze.addSuperInterface(superInterface);
            interfaze.addImportedType( new FullyQualifiedJavaType(configuration.getTargetPackage() + "."+introspectedTable.getFullyQualifiedTable().getDomainObjectName()));
            interfaze.addImportedType(superInterface);
        }

        if (stringHasValue(rootInterface3)) {
            interfaze.addImportedType(new FullyQualifiedJavaType(rootInterface3));
            rootInterface3 += "<"+ introspectedTable.getFullyQualifiedTable().getDomainObjectName()+ ">";
            FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(rootInterface3);
            interfaze.addSuperInterface(superInterface);
            interfaze.addImportedType( new FullyQualifiedJavaType(configuration.getTargetPackage() + "."+introspectedTable.getFullyQualifiedTable().getDomainObjectName()));
            interfaze.addImportedType(superInterface);
        }

        if (stringHasValue(rootInterface4)) {
            interfaze.addImportedType(new FullyQualifiedJavaType(rootInterface4));
            rootInterface4 += "<"+ introspectedTable.getFullyQualifiedTable().getDomainObjectName()+ ">";
            FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(rootInterface4);
            interfaze.addSuperInterface(superInterface);
            interfaze.addImportedType( new FullyQualifiedJavaType(configuration.getTargetPackage() + "."+introspectedTable.getFullyQualifiedTable().getDomainObjectName()));
            interfaze.addImportedType(superInterface);
        }

        if (stringHasValue(rootInterface5)) {
            interfaze.addImportedType(new FullyQualifiedJavaType(rootInterface5));
            rootInterface5 += "<"+ introspectedTable.getFullyQualifiedTable().getDomainObjectName()+ ">";
            FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(rootInterface5);
            interfaze.addSuperInterface(superInterface);
            interfaze.addImportedType( new FullyQualifiedJavaType(configuration.getTargetPackage() + "."+introspectedTable.getFullyQualifiedTable().getDomainObjectName()));
            interfaze.addImportedType(superInterface);
        }

        if (stringHasValue(rootInterface6)) {
            interfaze.addImportedType(new FullyQualifiedJavaType(rootInterface6));
            rootInterface6 += "<"+ introspectedTable.getFullyQualifiedTable().getDomainObjectName()+ ">";
            FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(rootInterface6);
            interfaze.addSuperInterface(superInterface);
            interfaze.addImportedType( new FullyQualifiedJavaType(configuration.getTargetPackage() + "."+introspectedTable.getFullyQualifiedTable().getDomainObjectName()));
            interfaze.addImportedType(superInterface);
        }

        if (stringHasValue(rootInterface7)) {
            interfaze.addImportedType(new FullyQualifiedJavaType(rootInterface7));
            rootInterface7 += "<"+ introspectedTable.getFullyQualifiedTable().getDomainObjectName()+ ">";
            FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(rootInterface7);
            interfaze.addSuperInterface(superInterface);
            interfaze.addImportedType( new FullyQualifiedJavaType(configuration.getTargetPackage() + "."+introspectedTable.getFullyQualifiedTable().getDomainObjectName()));
            interfaze.addImportedType(superInterface);
        }

        if (stringHasValue(rootInterface8)) {
            interfaze.addImportedType(new FullyQualifiedJavaType(rootInterface8));
            rootInterface8 += "<"+ introspectedTable.getFullyQualifiedTable().getDomainObjectName()+ ">";
            FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(rootInterface8);
            interfaze.addSuperInterface(superInterface);
            interfaze.addImportedType( new FullyQualifiedJavaType(configuration.getTargetPackage() + "."+introspectedTable.getFullyQualifiedTable().getDomainObjectName()));
            interfaze.addImportedType(superInterface);
        }

        if (stringHasValue(rootInterface9)) {
            interfaze.addImportedType(new FullyQualifiedJavaType(rootInterface9));
            rootInterface9 += "<"+ introspectedTable.getFullyQualifiedTable().getDomainObjectName()+ ">";
            FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(rootInterface9);
            interfaze.addSuperInterface(superInterface);
            interfaze.addImportedType( new FullyQualifiedJavaType(configuration.getTargetPackage() + "."+introspectedTable.getFullyQualifiedTable().getDomainObjectName()));
            interfaze.addImportedType(superInterface);
        }

        if (stringHasValue(rootInterface10)) {
            interfaze.addImportedType(new FullyQualifiedJavaType(rootInterface10));
            rootInterface10 += "<"+ introspectedTable.getFullyQualifiedTable().getDomainObjectName()+ ">";
            FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(rootInterface10);
            interfaze.addSuperInterface(superInterface);
            interfaze.addImportedType( new FullyQualifiedJavaType(configuration.getTargetPackage() + "."+introspectedTable.getFullyQualifiedTable().getDomainObjectName()));
            interfaze.addImportedType(superInterface);
        }

        interfaze.addJavaDocLine("/**");
        interfaze.addJavaDocLine(" * GBM.mapper 数据表："+introspectedTable.getFullyQualifiedTable().getIntrospectedTableName() + "("+introspectedTable.getRemarks()+")");
        interfaze.addJavaDocLine(" * Tool generation time " + new Date().toString());
        interfaze.addJavaDocLine(" */");

        interfaze.addAnnotation("@Repository");
        FullyQualifiedJavaType superInterface = new FullyQualifiedJavaType(rootInterface5);
        interfaze.addSuperInterface(superInterface);
        interfaze.addImportedType( new FullyQualifiedJavaType("org.springframework.stereotype.Repository"));
        interfaze.addImportedType(superInterface);

        interfaze.getMethods().clear();
        return super.clientGenerated(interfaze, topLevelClass, introspectedTable);
    }

    @Override
    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        String rootClass = context.getJavaModelGeneratorConfiguration().getProperty(EXAMPLE_ROOT_CLASS);
        String exampleFlag = context.getJavaModelGeneratorConfiguration().getProperty(EXAMPLEFLAG);
        if(!stringHasValue(exampleFlag)){
            return false;
        }
        if("false".equals(exampleFlag)){
            return false;
        }
        if(!stringHasValue(rootClass)){
            return true;
        }
        if (stringHasValue(rootClass)) {
            FullyQualifiedJavaType superClass = new FullyQualifiedJavaType(rootClass);
            topLevelClass.setSuperClass(superClass);
            topLevelClass.addImportedType(superClass);
        }
        topLevelClass.getInnerClasses().remove(2);// remove Criterion

        List<Method> methods = topLevelClass.getInnerClasses().get(0).getMethods();
        List<Method> newMethods = new ArrayList<Method>();
        for (Method method : methods) {
            if (!"addCriterion".equals(method.getName())) {
                newMethods.add(method);
            }
        }
        topLevelClass.getInnerClasses().get(0).getMethods().clear();
        addCriterionMethods(topLevelClass.getInnerClasses().get(0));
        topLevelClass.getInnerClasses().get(0).getMethods().addAll(newMethods);

        CommentGenerator commentGenerator = context.getCommentGenerator();

        Method method = createMethod(JavaVisibility.PUBLIC, FullyQualifiedJavaType.getCriteriaInstance(), "getCriteria");
        method.addBodyLine("if (oredCriteria.size() == 0) {createCriteria();}");
        method.addBodyLine("return oredCriteria.get(0);");
        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        topLevelClass.addMethod(method);

        method = createMethod(JavaVisibility.PUBLIC, null, "addCriteria");
        method.addParameter(new Parameter(new FullyQualifiedJavaType("java.util.List<Criterion>"), "criteria"));
        method.addBodyLine("getCriteria().getCriteria().addAll(criteria);");
        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        topLevelClass.addMethod(method);

        return super.modelExampleClassGenerated(topLevelClass, introspectedTable);
    }

    private void addCriterionMethods(InnerClass innerClass) {

        innerClass.addField(createField(JavaVisibility.PRIVATE, new FullyQualifiedJavaType("boolean"), "ignoreNull"));

        Method method = createMethod(JavaVisibility.PRIVATE, new FullyQualifiedJavaType("boolean"), "isIgnoreNull");
        method.addBodyLine("return ignoreNull;");
        innerClass.addMethod(method);

        method = createMethod(JavaVisibility.PUBLIC, new FullyQualifiedJavaType("Criteria"), "ignoreNull");
        method.addBodyLine("this.ignoreNull = true;");
        method.addBodyLine("return (Criteria) this;");
        innerClass.addMethod(method);

        method = createMethod(JavaVisibility.PROTECTED, null, "addCriterion");
        method.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "condition"));
        method.addBodyLine("if (condition == null) {");
        method.addBodyLine("if (!isIgnoreNull()) {");
        method.addBodyLine("throw new RuntimeException(\"Value for condition cannot be null\");");
        method.addBodyLine("}} else {");
        method.addBodyLine("criteria.add(new Criterion(condition));}");
        innerClass.addMethod(method);

        method = createMethod(JavaVisibility.PROTECTED, null, "addCriterion");
        method.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "condition"));
        method.addParameter(new Parameter(FullyQualifiedJavaType.getObjectInstance(), "value"));
        method.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "property"));
        method.addBodyLine("if (value == null) {");
        method.addBodyLine("if (!isIgnoreNull()) {");
        method.addBodyLine("throw new RuntimeException(\"Value for \" + property + \" cannot be null\");");
        method.addBodyLine("}} else {");
        method.addBodyLine("criteria.add(new Criterion(condition, value));}");
        innerClass.addMethod(method);

        method = createMethod(JavaVisibility.PROTECTED, null, "addCriterion");
        method.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "condition"));
        method.addParameter(new Parameter(FullyQualifiedJavaType.getObjectInstance(), "value1"));
        method.addParameter(new Parameter(FullyQualifiedJavaType.getObjectInstance(), "value2"));
        method.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "property"));
        method.addBodyLine("if (value1 == null || value2 == null) {");
        method.addBodyLine("if (!isIgnoreNull()) {");
        method.addBodyLine("throw new RuntimeException(\"Between values for \" + property + \" cannot be null\");");
        method.addBodyLine("}} else {");
        method.addBodyLine("criteria.add(new Criterion(condition, value1, value2));}");
        innerClass.addMethod(method);
    }
    @Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        String apiModelPropertyFlag  = context.getCommentGeneratorConfiguration().getProperty(APIMODELPROPERTYFLAG);
        String dtoFlag  = context.getCommentGeneratorConfiguration().getProperty(DTOFLAG);

        topLevelClass.addJavaDocLine("/**");
        if(stringHasValue(dtoFlag) && "true".equals(dtoFlag)){
            topLevelClass.addJavaDocLine(" * GBM.DTO 数据表："+introspectedTable.getFullyQualifiedTable().getIntrospectedTableName() + "("+introspectedTable.getRemarks()+")");
        }else {
            topLevelClass.addJavaDocLine(" * GBM.model 数据表："+introspectedTable.getFullyQualifiedTable().getIntrospectedTableName() + "("+introspectedTable.getRemarks()+")");
        }
        topLevelClass.addJavaDocLine(" * Tool generation time " + new Date().toString());
        topLevelClass.addJavaDocLine(" */");

        //topLevelClass.addAnnotation("@Builder");
        //topLevelClass.addAnnotation("@NoArgsConstructor");
        //topLevelClass.addAnnotation("@AllArgsConstructor");
        topLevelClass.addAnnotation("@Data");
        topLevelClass.addImportedType("lombok.Data");
        //topLevelClass.addImportedType("lombok.NoArgsConstructor");
        //topLevelClass.addImportedType("lombok.AllArgsConstructor");
        //topLevelClass.addImportedType("lombok.Builder");

        if(!(stringHasValue(dtoFlag) && "true".equals(dtoFlag))){
            topLevelClass.addAnnotation("@Table(name = \""+introspectedTable.getFullyQualifiedTable().getIntrospectedTableName()+"\")");
            topLevelClass.addImportedType("javax.persistence.Id");
            topLevelClass.addImportedType("javax.persistence.Table");
            topLevelClass.addImportedType("javax.persistence.GeneratedValue");
            topLevelClass.addImportedType("javax.persistence.Column");
            topLevelClass.addImportedType("tk.mybatis.mapper.annotation.ColumnType");
            /*topLevelClass.addImportedType("tk.mybatis.mapper.annotation.LogicDelete");
            topLevelClass.addImportedType("tk.mybatis.mapper.annotation.Version");*/
        }

        if( !(stringHasValue(apiModelPropertyFlag) && "false".equals(apiModelPropertyFlag)) ){
            topLevelClass.addAnnotation("@ApiModel(value = \""+introspectedTable.getRemarks()+"\")");
            topLevelClass.addImportedType("io.swagger.annotations.ApiModel");
            topLevelClass.addImportedType("io.swagger.annotations.ApiModelProperty");
        }

        return true;
    }
    @Override
    public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        return false;
    }
    @Override
    public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        return false;
    }

    public boolean clientCountByExampleMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }
    public boolean clientCountByExampleMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientDeleteByExampleMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientDeleteByExampleMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientDeleteByPrimaryKeyMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientDeleteByPrimaryKeyMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientInsertMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientInsertMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientSelectByExampleWithBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientSelectByExampleWithBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientSelectByExampleWithoutBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientSelectByExampleWithoutBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientSelectByPrimaryKeyMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientSelectByPrimaryKeyMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientUpdateByExampleSelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientUpdateByExampleSelectiveMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientUpdateByExampleWithBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientUpdateByExampleWithBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientUpdateByExampleWithoutBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientUpdateByExampleWithoutBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientUpdateByPrimaryKeySelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientUpdateByPrimaryKeySelectiveMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientUpdateByPrimaryKeyWithBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientUpdateByPrimaryKeyWithBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientUpdateByPrimaryKeyWithoutBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientUpdateByPrimaryKeyWithoutBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapResultMapWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean sqlMapCountByExampleElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapDeleteByExampleElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapDeleteByPrimaryKeyElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapExampleWhereClauseElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }


    public boolean sqlMapInsertElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapResultMapWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapSelectByExampleWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapSelectByPrimaryKeyElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapUpdateByExampleSelectiveElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapUpdateByExampleWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapUpdateByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapUpdateByPrimaryKeySelectiveElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapUpdateByPrimaryKeyWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapUpdateByPrimaryKeyWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapInsertSelectiveElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientInsertSelectiveMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientInsertSelectiveMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return false;
    }

    public void initialized(IntrospectedTable introspectedTable) {
    }

    public boolean sqlMapBaseColumnListElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean sqlMapBlobColumnListElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean providerGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean providerApplyWhereMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean providerCountByExampleMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean providerDeleteByExampleMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean providerInsertSelectiveMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean providerSelectByExampleWithBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean providerSelectByExampleWithoutBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean providerUpdateByExampleSelectiveMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean providerUpdateByExampleWithBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean providerUpdateByExampleWithoutBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean providerUpdateByPrimaryKeySelectiveMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean clientSelectAllMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean clientSelectAllMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        return true;
    }

    public boolean sqlMapSelectAllElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }
    @Override
    public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
    	/*addQueryExpand(element);
    	addGroupByClause(element);
        addLimit(element);
        return super.sqlMapSelectByExampleWithoutBLOBsElementGenerated(element, introspectedTable);*/
    	return false;
    }

    private FullyQualifiedJavaType getPrimaryKeyType(IntrospectedTable introspectedTable) {
        return introspectedTable.getPrimaryKeyColumns().get(0).getFullyQualifiedJavaType();
    }
    
    private void addQueryExpand(XmlElement element) {
    	int last = element.getElements().size() - 1;
    	Element groupByClause = element.getElements().get(last);
    	element.getElements().remove(last);
    	
    	XmlElement ifElement = new XmlElement("if");
    	ifElement.addAttribute(new Attribute("test", "queryExpand != null"));
    	ifElement.addElement(new TextElement("${queryExpand}"));
    	
    	element.addElement(ifElement);
    	element.addElement(groupByClause);
    }

    private void addLimit(XmlElement element) {
        XmlElement ifElement = new XmlElement("if");
        ifElement.addAttribute(new Attribute("test", "limit gte 1 and offset gte 0"));
        ifElement.addElement(new TextElement("limit #{limit} offset #{offset}"));
        element.addElement(ifElement);
    }

    private void addGroupByClause(XmlElement element) {
        int last = element.getElements().size() - 1;
        Element orderByClause = element.getElements().get(last);
        element.getElements().remove(last);

        XmlElement ifElement = new XmlElement("if");
        ifElement.addAttribute(new Attribute("test", "groupByClause != null"));
        ifElement.addElement(new TextElement("group by ${groupByClause}"));

        element.addElement(ifElement);
        element.addElement(orderByClause);
    }

    private Field createField(JavaVisibility visibility, FullyQualifiedJavaType fieldType, String fieldName) {
        Field field = new Field();
        field.setVisibility(visibility);
        field.setType(fieldType);
        field.setName(fieldName);
        return field;
    }

    private Method createMethod(JavaVisibility visibility, FullyQualifiedJavaType returnType, String methodName) {
        return createMethod(visibility, returnType, methodName, null, null);
    }

    private Method createMethod(JavaVisibility visibility, FullyQualifiedJavaType returnType, String methodName, Parameter parameter, String bodyLine) {
        Method method = new Method();
        method.setVisibility(visibility);
        if (returnType != null) {
            method.setReturnType(returnType);
        }
        method.setName(methodName);
        if (parameter != null) {
            method.addParameter(parameter);
        }
        if (stringHasValue(bodyLine)) {
            method.addBodyLine(bodyLine);
        }
        return method;
    }

}
